core: A bit more daemon work
authorColin Walters <walters@verbum.org>
Tue, 22 Nov 2011 15:02:49 +0000 (10:02 -0500)
committerColin Walters <walters@verbum.org>
Tue, 22 Nov 2011 15:02:49 +0000 (10:02 -0500)
Makefile-daemon.am
src/daemon/main.c [deleted file]
src/daemon/ostreed.c [new file with mode: 0644]
src/daemon/ot-daemon.c
src/daemon/ot-daemon.h

index 898e2f9c4d9a94df03a5f4089e7c51eb195c36d3..c1d21e98423a3daa5024a9aa8c46cbcd7540a9f5 100644 (file)
@@ -19,7 +19,7 @@
 
 libexec_PROGRAMS += ostreed
 
-ostreed_SOURCES = src/daemon/main.c \
+ostreed_SOURCES = src/daemon/ostreed.c \
        src/daemon/ot-daemon.h \
        src/daemon/ot-daemon.c \
        $(NULL)
diff --git a/src/daemon/main.c b/src/daemon/main.c
deleted file mode 100644 (file)
index eda32e8..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2011 Colin Walters <walters@verbum.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Colin Walters <walters@verbum.org>
- */
-
-#include "config.h"
-
-#include "ostree.h"
-#include "ot-daemon.h"
-
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-int
-main (int    argc,
-      char **argv)
-{
-  OstreeDaemon *daemon = NULL;
-
-  g_type_init ();
-
-  g_set_prgname (argv[0]);
-
-  if (getuid () != 0)
-    {
-      g_printerr ("This program must be run as root\n");
-      exit (1);
-    }
-
-  daemon = ostree_daemon_new ();
-
-  g_main_loop_run (daemon->loop);
-
-  return 0;
-}
diff --git a/src/daemon/ostreed.c b/src/daemon/ostreed.c
new file mode 100644 (file)
index 0000000..eda32e8
--- /dev/null
@@ -0,0 +1,53 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters@verbum.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Colin Walters <walters@verbum.org>
+ */
+
+#include "config.h"
+
+#include "ostree.h"
+#include "ot-daemon.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+int
+main (int    argc,
+      char **argv)
+{
+  OstreeDaemon *daemon = NULL;
+
+  g_type_init ();
+
+  g_set_prgname (argv[0]);
+
+  if (getuid () != 0)
+    {
+      g_printerr ("This program must be run as root\n");
+      exit (1);
+    }
+
+  daemon = ostree_daemon_new ();
+
+  g_main_loop_run (daemon->loop);
+
+  return 0;
+}
index cb3e275a96564d134b1ac323aef68ec393dedaad..d7793b791f78a4fab248d86674d254faaf3cf113 100644 (file)
@@ -51,12 +51,143 @@ static const gchar introspection_xml[] =
   "      <arg type='s' name='revision' direction='in'/>"
   "      <arg type='u' name='op_id' direction='out'/>"
   "    </method>"
-  "    <method name='OverlayTar'>"
-  "      <arg type='s' name='filename' direction='in'/>"
+  "    <method name='Overlay'>"
+  "      <arg type='s' name='dir' direction='in'/>"
   "      <arg type='u' name='op_id' direction='out'/>"
   "    </method>"
+  "    <method name='Diff'>"
+  "      <arg type='s' name='dir' direction='in'/>"
+  "      <arg type='h' name='handle' direction='out'/>"
+  "    </method>"
+  "    <signal name='OperationEnded'>"
+  "      <arg type='u' name='op_id' />"
+  "      <arg type='b' name='successful' />"
+  "      <arg type='s' name='result_str' />"
+  "    </signal>"
   "  </interface>"
   "</node>";
+
+static void
+operation_new (OstreeDaemon            *self,
+               const char              *sender,
+               guint                  *out_id,
+               OstreeDaemonOperation **out_op)
+{
+  
+  *out_id = ++self->op_id;
+  *out_op = g_new0 (OstreeDaemonOperation, 1);
+  (*out_op)->requestor_dbus_name = g_strdup (sender);
+  (*out_op)->cancellable = g_cancellable_new ();
+}
+
+static void
+operation_free (OstreeDaemonOperation   *op)
+{
+  g_free (op->requestor_dbus_name);
+  g_object_unref (op->cancellable);
+  g_free (op);
+}
+
+static gboolean
+op_return (OstreeDaemon          *self,
+           OstreeDaemonOperation *op,
+           GError                *error_return)
+{
+  gboolean ret = FALSE;
+  GVariant *args = NULL;
+
+  g_hash_table_remove (self->ops, GUINT_TO_POINTER (op->id));
+
+  if (error_return)
+    args = g_variant_new ("(ubs)", op->id, FALSE, error_return->message);
+  else
+    args = g_variant_new ("(ubs)", op->id, TRUE, "Success");
+
+  g_dbus_connection_emit_signal (self->bus,
+                                 op->requestor_dbus_name,
+                                 OSTREE_DAEMON_PATH,
+                                 OSTREE_DAEMON_IFACE,
+                                 "OperationEnded",
+                                 args,
+                                 NULL);
+
+  ret = TRUE;
+  operation_free (op);
+  if (args)
+    g_variant_unref (args);
+  return ret;
+}
+
+typedef struct {
+  OstreeDaemonOperation *op;
+  GFile *dir;
+} OverlayDirThreadData;
+
+typedef struct {
+  OverlayDirThreadData *tdata;
+  GError *error;
+} OverlayDirEmitInIdleData;
+
+static gboolean
+overlay_dir_emit_in_idle (gpointer data)
+{
+  OverlayDirEmitInIdleData *idledata = data;
+
+  op_return (idledata->tdata->op->daemon,
+             idledata->tdata->op,
+             idledata->error);
+             
+  g_free (idledata);
+  
+  return FALSE;
+}
+
+static gpointer
+overlay_dir_thread (gpointer data)
+{
+  OverlayDirThreadData *tdata = data;
+  GMainContext *context = NULL;
+  GFile *sysroot_f = NULL;
+  OverlayDirEmitInIdleData *idledata = g_new0 (OverlayDirEmitInIdleData, 1);
+  idledata->tdata = tdata;
+
+  context = g_main_context_new ();
+
+  sysroot_f = ot_gfile_new_for_path ("/sysroot/ostree/current");
+
+  g_main_context_push_thread_default (context);
+
+  (void)ot_gfile_merge_dirs (sysroot_f,
+                             tdata->dir,
+                             tdata->op->cancellable,
+                             &(idledata->error));
+  g_idle_add (overlay_dir_emit_in_idle, idledata);
+  
+  g_main_context_pop_thread_default (context);
+
+  g_main_context_unref (context);
+
+  g_clear_object (&tdata->dir);
+  g_free (tdata);
+  
+  return NULL;
+}
+
+static void
+do_op_overlay (OstreeDaemon            *self,
+               const char              *dir,
+               OstreeDaemonOperation   *op)
+{
+  OverlayDirThreadData *tdata = g_new0 (OverlayDirThreadData, 1);
+  
+  tdata->op = op;
+  tdata->dir = ot_gfile_new_for_path (dir);
+
+  g_thread_create_full (overlay_dir_thread, tdata, 0, FALSE, FALSE,
+                        G_THREAD_PRIORITY_NORMAL, NULL);
+}
+
 static void
 handle_method_call (GDBusConnection       *connection,
                     const gchar           *sender,
@@ -67,6 +198,23 @@ handle_method_call (GDBusConnection       *connection,
                     GDBusMethodInvocation *invocation,
                     gpointer               user_data)
 {
+  OstreeDaemon *self = user_data;
+  guint32 op_id;
+  OstreeDaemonOperation *op;
+
+  if (g_strcmp0 (method_name, "Overlay") == 0)
+    {
+      const gchar *dirpath;
+
+      g_variant_get (parameters, "(&s)", &dirpath);
+
+      operation_new (self, sender, &op_id, &op);
+
+      do_op_overlay (self, dirpath, op);
+
+      g_dbus_method_invocation_return_value (invocation,
+                                             g_variant_new ("(u)", op_id));
+    }
 }
 
 static const GDBusInterfaceVTable interface_vtable =
@@ -81,10 +229,13 @@ on_bus_acquired (GDBusConnection *connection,
                  const gchar     *name,
                  gpointer         user_data)
 {
+  OstreeDaemon *self = user_data;
   guint id;
 
+  self->bus = g_object_ref (connection);
+
   id = g_dbus_connection_register_object (connection,
-                                          "/org/gnome/OSTree",
+                                          OSTREE_DAEMON_PATH,
                                           introspection_data->interfaces[0],
                                           &interface_vtable,
                                           NULL,  /* user_data */
@@ -98,11 +249,11 @@ on_name_acquired (GDBusConnection *connection,
                   const gchar     *name,
                   gpointer         user_data)
 {
-  OstreeDaemon *daemon = user_data;
+  OstreeDaemon *self = user_data;
   GError *error = NULL;
 
-  daemon->repo = ostree_repo_new ("/sysroot/ostree/repo");
-  if (!ostree_repo_check (daemon->repo, &error))
+  self->repo = ostree_repo_new ("/sysroot/ostree/repo");
+  if (!ostree_repo_check (self->repo, &error))
     {
       g_printerr ("%s\n", error->message);
       g_clear_error (&error);
@@ -118,7 +269,6 @@ on_name_lost (GDBusConnection *connection,
   exit (1);
 }
 
-
 OstreeDaemon *
 ostree_daemon_new (void)
 {
@@ -126,10 +276,8 @@ ostree_daemon_new (void)
 
   ret->loop = g_main_loop_new (NULL, TRUE);
 
-  introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
-
   ret->name_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
-                                 "org.gnome.OSTree",
+                                 OSTREE_DAEMON_NAME,
                                  G_BUS_NAME_OWNER_FLAGS_NONE,
                                  on_bus_acquired,
                                  on_name_acquired,
@@ -137,6 +285,8 @@ ostree_daemon_new (void)
                                  NULL,
                                  NULL);
 
+  ret->ops = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, NULL);
+
   return ret;
 }
 
index 4077bf1a4b38c55c9d6956a4868b29ac6f4b8390..b0d87788f8db47e681c9f49163994b7e5d411eb5 100644 (file)
 
 #include <gio/gio.h>
 
+#define OSTREE_DAEMON_NAME "org.gnome.OSTree"
+#define OSTREE_DAEMON_PATH "/org/gnome/OSTree"
+#define OSTREE_DAEMON_IFACE "org.gnome.OSTree"
+
 G_BEGIN_DECLS
 
 typedef struct {
   GMainLoop *loop;
   OstreeRepo  *repo;
 
+  GDBusConnection *bus;
+
   int name_id;
+
+  guint32 op_id;
+
+  GHashTable *ops;
 } OstreeDaemon;
 
+typedef struct {
+  guint32 id;
+  OstreeDaemon *daemon;
+  char *requestor_dbus_name;
+  GCancellable *cancellable;
+} OstreeDaemonOperation;
+
 OstreeDaemon *ostree_daemon_new (void);
 
 G_END_DECLS